; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -global-isel=0 -mtriple=amdgcn-amd-amdpal -mcpu=tahiti < %s | FileCheck -check-prefixes=CHECK,SDAG %s
; RUN: llc -global-isel=1 -mtriple=amdgcn-amd-amdpal -mcpu=tahiti < %s | FileCheck -check-prefixes=CHECK,GISEL %s

define ptr @global_to_flat_addrspacecast(ptr addrspace(1) %ptr) {
; CHECK-LABEL: global_to_flat_addrspacecast:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT:    s_setpc_b64 s[30:31]
  %stof = addrspacecast ptr addrspace(1) %ptr to ptr
  ret ptr %stof
}

define ptr addrspace(1) @flat_to_gobal_addrspacecast(ptr %ptr) {
; CHECK-LABEL: flat_to_gobal_addrspacecast:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT:    s_setpc_b64 s[30:31]
  %stof = addrspacecast ptr %ptr to ptr addrspace(1)
  ret ptr addrspace(1) %stof
}

define ptr @group_to_flat_addrspacecast(ptr addrspace(3) %ptr) {
; CHECK-LABEL: group_to_flat_addrspacecast:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT:    s_load_dword s4, s[6:7], 0x10
; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, -1, v0
; CHECK-NEXT:    v_cndmask_b32_e32 v0, 0, v0, vcc
; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
; CHECK-NEXT:    v_mov_b32_e32 v1, s4
; CHECK-NEXT:    v_cndmask_b32_e32 v1, 0, v1, vcc
; CHECK-NEXT:    s_setpc_b64 s[30:31]
  %stof = addrspacecast ptr addrspace(3) %ptr to ptr
  ret ptr %stof
}

define ptr addrspace(3) @flat_to_group_addrspacecast(ptr %ptr) {
; CHECK-LABEL: flat_to_group_addrspacecast:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT:    v_cmp_ne_u64_e32 vcc, 0, v[0:1]
; CHECK-NEXT:    v_cndmask_b32_e32 v0, -1, v0, vcc
; CHECK-NEXT:    s_setpc_b64 s[30:31]
  %stof = addrspacecast ptr %ptr to ptr addrspace(3)
  ret ptr addrspace(3) %stof
}

define ptr @private_to_flat_addrspacecast(ptr addrspace(5) %ptr) {
; CHECK-LABEL: private_to_flat_addrspacecast:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT:    s_load_dword s4, s[6:7], 0x11
; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc, -1, v0
; CHECK-NEXT:    v_cndmask_b32_e32 v0, 0, v0, vcc
; CHECK-NEXT:    s_waitcnt lgkmcnt(0)
; CHECK-NEXT:    v_mov_b32_e32 v1, s4
; CHECK-NEXT:    v_cndmask_b32_e32 v1, 0, v1, vcc
; CHECK-NEXT:    s_setpc_b64 s[30:31]
  %stof = addrspacecast ptr addrspace(5) %ptr to ptr
  ret ptr %stof
}

define ptr addrspace(5) @flat_to_private_addrspacecast(ptr %ptr) {
; CHECK-LABEL: flat_to_private_addrspacecast:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT:    v_cmp_ne_u64_e32 vcc, 0, v[0:1]
; CHECK-NEXT:    v_cndmask_b32_e32 v0, -1, v0, vcc
; CHECK-NEXT:    s_setpc_b64 s[30:31]
  %stof = addrspacecast ptr %ptr to ptr addrspace(5)
  ret ptr addrspace(5) %stof
}

define ptr addrspace(6) @constant_to_constant32_addrspacecast(ptr addrspace(4) %ptr, i32 %offset) {
; CHECK-LABEL: constant_to_constant32_addrspacecast:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
; CHECK-NEXT:    s_setpc_b64 s[30:31]
  %addrspacecast = addrspacecast ptr addrspace(4) %ptr to ptr addrspace(6)
  %gep = getelementptr i8, ptr addrspace(6) %addrspacecast, i32 %offset
  ret ptr addrspace(6) %gep
}

define ptr addrspace(6) @global_to_constant32_addrspacecast(ptr addrspace(1) %ptr, i32 %offset) {
; CHECK-LABEL: global_to_constant32_addrspacecast:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
; CHECK-NEXT:    s_setpc_b64 s[30:31]
  %addrspacecast = addrspacecast ptr addrspace(1) %ptr to ptr addrspace(6)
  %gep = getelementptr i8, ptr addrspace(6) %addrspacecast, i32 %offset
  ret ptr addrspace(6) %gep
}

define ptr @constant32bit_to_flat_addrspacecast_0(ptr addrspace(6) %ptr) {
; CHECK-LABEL: constant32bit_to_flat_addrspacecast_0:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT:    v_mov_b32_e32 v1, 0
; CHECK-NEXT:    s_setpc_b64 s[30:31]
  %stof = addrspacecast ptr addrspace(6) %ptr to ptr
  ret ptr %stof
}

define ptr @constant32bit_to_flat_addrspacecast_1(ptr addrspace(6) %ptr) #0 {
; CHECK-LABEL: constant32bit_to_flat_addrspacecast_1:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT:    v_mov_b32_e32 v1, 0xffff8000
; CHECK-NEXT:    s_setpc_b64 s[30:31]
  %stof = addrspacecast ptr addrspace(6) %ptr to ptr
  ret ptr %stof
}

define ptr @constant32bit_to_flat_addrspacecast_null() {
; CHECK-LABEL: constant32bit_to_flat_addrspacecast_null:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT:    v_mov_b32_e32 v0, 0
; CHECK-NEXT:    v_mov_b32_e32 v1, 0
; CHECK-NEXT:    s_setpc_b64 s[30:31]
  %stof = addrspacecast ptr addrspace(6) null to ptr
  ret ptr %stof
}

define ptr @constant32bit_to_flat_addrspacecast_undef() #0 {
; SDAG-LABEL: constant32bit_to_flat_addrspacecast_undef:
; SDAG:       ; %bb.0:
; SDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; SDAG-NEXT:    v_mov_b32_e32 v1, 0
; SDAG-NEXT:    s_setpc_b64 s[30:31]
;
; GISEL-LABEL: constant32bit_to_flat_addrspacecast_undef:
; GISEL:       ; %bb.0:
; GISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GISEL-NEXT:    s_setpc_b64 s[30:31]
  %stof = addrspacecast ptr addrspace(6) undef to ptr
  ret ptr %stof
}

define ptr @constant32bit_to_flat_addrspacecast_poison() #0 {
; SDAG-LABEL: constant32bit_to_flat_addrspacecast_poison:
; SDAG:       ; %bb.0:
; SDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; SDAG-NEXT:    v_mov_b32_e32 v1, 0
; SDAG-NEXT:    s_setpc_b64 s[30:31]
;
; GISEL-LABEL: constant32bit_to_flat_addrspacecast_poison:
; GISEL:       ; %bb.0:
; GISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GISEL-NEXT:    s_setpc_b64 s[30:31]
  %stof = addrspacecast ptr addrspace(6) poison to ptr
  ret ptr %stof
}

define ptr @constant32bit_to_flat_addrspacecast_constant() #0 {
; CHECK-LABEL: constant32bit_to_flat_addrspacecast_constant:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT:    v_mov_b32_e32 v0, 0x3039
; CHECK-NEXT:    v_mov_b32_e32 v1, 0xffff8000
; CHECK-NEXT:    s_setpc_b64 s[30:31]
  %stof = addrspacecast ptr addrspace(6) inttoptr (i32 12345 to ptr addrspace(6)) to ptr
  ret ptr %stof
}

define ptr addrspace(1) @addrspacecast_flat_null_to_global() {
; CHECK-LABEL: addrspacecast_flat_null_to_global:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT:    v_mov_b32_e32 v0, 0
; CHECK-NEXT:    v_mov_b32_e32 v1, 0
; CHECK-NEXT:    s_setpc_b64 s[30:31]
  ret ptr addrspace(1) addrspacecast (ptr null to ptr addrspace(1))
}

define ptr addrspace(3) @addrspacecast_flat_null_to_group() {
; CHECK-LABEL: addrspacecast_flat_null_to_group:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT:    v_mov_b32_e32 v0, -1
; CHECK-NEXT:    s_setpc_b64 s[30:31]
  ret ptr addrspace(3) addrspacecast (ptr null to ptr addrspace(3))
}

define ptr addrspace(5) @addrspacecast_flat_null_to_private() {
; CHECK-LABEL: addrspacecast_flat_null_to_private:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT:    v_mov_b32_e32 v0, -1
; CHECK-NEXT:    s_setpc_b64 s[30:31]
  ret ptr addrspace(5) addrspacecast (ptr null to ptr addrspace(5))
}

define ptr addrspace(6) @addrspacecast_flat_null_to_constant32bit() {
; CHECK-LABEL: addrspacecast_flat_null_to_constant32bit:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT:    v_mov_b32_e32 v0, 0
; CHECK-NEXT:    s_setpc_b64 s[30:31]
  ret ptr addrspace(6) addrspacecast (ptr null to ptr addrspace(6))
}

attributes #0 = { "amdgpu-32bit-address-high-bits"="0xffff8000" }
